package com.lancoo.edu.platform.operation.backupRestore.service.bo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lancoo.edu.platform.operation.backupRestore.constant.BackupRestoreConstant;
import com.lancoo.edu.platform.operation.backupRestore.domain.po.BrBackupInfo;
import com.lancoo.edu.platform.operation.backupRestore.domain.po.BrProductSysInfo;
import com.lancoo.edu.platform.operation.backupRestore.domain.po.BrServerSysInfo;
import com.lancoo.edu.platform.operation.backupRestore.domain.po.BrSysDatabaseInfo;
import com.lancoo.edu.platform.operation.backupRestore.domain.vo.BackupRecordeProductVo;
import com.lancoo.edu.platform.operation.backupRestore.domain.vo.BackupRecordeSysVo;
import com.lancoo.edu.platform.operation.backupRestore.domain.vo.BrBackupInfoRestoreAllVo;
import com.lancoo.edu.platform.operation.backupRestore.domain.vo.BrBackupInfoVo;
import com.lancoo.edu.platform.operation.backupRestore.service.po.BrBackupInfoService;
import com.lancoo.edu.platform.operation.backupRestore.service.po.BrProductSysInfoService;
import com.lancoo.edu.platform.operation.backupRestore.service.po.BrServerSysInfoService;
import com.lancoo.edu.platform.operation.backupRestore.service.po.BrSysDatabaseInfoService;
import com.lancoo.edu.platform.operation.commons.config.LancooConfig;
import com.lancoo.edu.platform.operation.commons.utils.ListUtil;
import com.lancoo.edu.platform.operation.commons.utils.PageUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lzh
 * @Date 2024/4/3 16:17
 */
@Service
@AllArgsConstructor
public class BrBackupRecordeBoService {

    private final BrProductSysInfoService brProductSysInfoService;
    private final BrServerSysInfoService brServerSysInfoService;
    private final BrBackupInfoService brBackupInfoService;
    private final BrSysDatabaseInfoService brSysDatabaseInfoService;
    private final LancooConfig lancooConfig;

    /**
     * 获取备份记录列表
     *
     * @param eduId 教育局ID
     * @param keyword  关键字
     * @return 备份记录列表
     */
    public IPage<BackupRecordeProductVo> getBackupRecordeList(String eduId, String keyword, Integer pageNum, Integer pageSize) {
        List<BackupRecordeProductVo> backupRecordeProductVoList = new ArrayList<>();
        // 1、当关键字为空时，查询一次
        if (StringUtils.isBlank(keyword)) {
            backupRecordeProductVoList = getBackupRecordeProductVoForProductKeyword(eduId, keyword);
            return PageUtil.getPage(pageNum, pageSize, backupRecordeProductVoList);
        }
        // 2、关键字查询系统名称
        List<BackupRecordeProductVo> backupRecordeProductVoForSysKeyword = getBackupRecordeProductVoForSysKeyword(eduId, keyword);
        if (CollectionUtil.isNotEmpty(backupRecordeProductVoForSysKeyword)) {
            backupRecordeProductVoList.addAll(backupRecordeProductVoForSysKeyword);
        }
        // 3、关键字查询产品名称
        List<BackupRecordeProductVo> backupRecordeProductVoForProductKeyword = getBackupRecordeProductVoForProductKeyword(eduId, keyword);
        if (CollectionUtil.isNotEmpty(backupRecordeProductVoForProductKeyword)) {
            backupRecordeProductVoList.addAll(backupRecordeProductVoForProductKeyword);
        }
        backupRecordeProductVoList = backupRecordeProductVoList.stream().filter(ListUtil.distinctByKey(BackupRecordeProductVo::getProductId)).sorted(Comparator.comparing(BackupRecordeProductVo::getProductId)).collect(Collectors.toList());
        // 4、分页
        return PageUtil.getPage(pageNum, pageSize, backupRecordeProductVoList);
    }

    /**
     * 获取产品对应系统备份记录列表---关键字查询产品名称
     *
     * @param eduId    教育局ID
     * @param keyword     关键字
     * @return 产品对应系统备份记录列表
     */
    private List<BackupRecordeProductVo> getBackupRecordeProductVoForProductKeyword(String eduId, String keyword) {
        // 1、查询产品列表
        List<BrProductSysInfo> brProductSysInfoList = brProductSysInfoService.getList(keyword);
        // 1.1、查询各个服务器上安装的系统
        List<BrServerSysInfo> serverSysInfoList = brServerSysInfoService.list();
        // 1.2、查询备份记录列表
        List<BrBackupInfo> brBackupInfoList = brBackupInfoService.getRecentlyBackup(eduId);
        // 1.3、系统信息
        List<BrSysDatabaseInfo> brSysDatabaseInfoList = brSysDatabaseInfoService.getList(null);
        // 2、产品对应系统备份记录列表
        return getBackupRecordeProductVoList(brProductSysInfoList, serverSysInfoList, brBackupInfoList, brSysDatabaseInfoList);
    }

    /**
     * 获取产品对应系统备份记录列表
     *
     * @param brProductSysInfoList  产品对应系统列表
     * @param serverSysInfoList     系统对应服务器列表
     * @param brBackupInfoList      系统备份记录列表
     * @param brSysDatabaseInfoList 系统信息列表
     * @return 产品对应系统备份记录列表
     */
    private List<BackupRecordeProductVo> getBackupRecordeProductVoList(List<BrProductSysInfo> brProductSysInfoList, List<BrServerSysInfo> serverSysInfoList, List<BrBackupInfo> brBackupInfoList, List<BrSysDatabaseInfo> brSysDatabaseInfoList) {
        List<String> sysIdList = serverSysInfoList.stream().map(BrServerSysInfo::getSysId).collect(Collectors.toList());
        Map<String, List<BrBackupInfo>> recordMap = brBackupInfoList.stream().filter(brBackupInfo -> sysIdList.contains(brBackupInfo.getSysId())).collect(Collectors.groupingBy(BrBackupInfo::getSysId));
        Map<String, List<BrSysDatabaseInfo>> sysInfoMap = brSysDatabaseInfoList.stream().filter(brSysDatabaseInfo -> sysIdList.contains(brSysDatabaseInfo.getSysId())).collect(Collectors.groupingBy(BrSysDatabaseInfo::getSysId));
        List<BackupRecordeProductVo> backupRecordeProductVoList = new ArrayList<>();
        String serviceUrl = lancooConfig.getServiceUrl();
        for (BrProductSysInfo brProductSysInfo : brProductSysInfoList) {
            BackupRecordeProductVo backupRecordeProductVo = BeanUtil.copyProperties(brProductSysInfo, BackupRecordeProductVo.class);
            // 设置产品图标地址
            backupRecordeProductVo.setProductLogoUrl(serviceUrl + "/" + brProductSysInfo.getProductLogoUrl());
            backupRecordeProductVoList.add(backupRecordeProductVo);
            // 过滤的到备份记录
            List<BackupRecordeSysVo> backupRecordeSysVoList = new ArrayList<>();
            for (String sysId : sysIdList) {
                if (!brProductSysInfo.getSysIdList().contains(sysId) || !sysInfoMap.containsKey(sysId)) {
                    continue;
                }
                BrSysDatabaseInfo brSysDatabaseInfo = sysInfoMap.get(sysId).get(0);
                BackupRecordeSysVo backupRecordeSysVo = BeanUtil.copyProperties(brSysDatabaseInfo, BackupRecordeSysVo.class);
                if (recordMap.containsKey(sysId)) {
                    BrBackupInfo brBackupInfo = recordMap.get(sysId).get(0);
                    backupRecordeSysVo.setId(brBackupInfo.getId());
                    backupRecordeSysVo.setBackupTime(brBackupInfo.getBackupTime());
                    backupRecordeSysVo.setBackupFilePath(brBackupInfo.getBackupFilePath());
                }
                // 设置系统图标地址
                if (StringUtils.isNotBlank(backupRecordeSysVo.getSysLogoUrl())){
                    backupRecordeSysVo.setSysLogoUrl(serviceUrl + "/" + backupRecordeSysVo.getSysLogoUrl());
                }
                backupRecordeSysVoList.add(backupRecordeSysVo);
            }
            backupRecordeProductVo.setBackupRecordeSysVoList(backupRecordeSysVoList);
        }
        return backupRecordeProductVoList.stream().filter(backupRecordeProductVo -> CollectionUtil.isNotEmpty(backupRecordeProductVo.getBackupRecordeSysVoList())).collect(Collectors.toList());
    }

    /**
     * 获取产品对应系统备份记录列表---关键字查询系统名称
     *
     * @param eduId    教育局ID
     * @param keyword     关键字
     * @return 产品对应系统备份记录列表
     */
    private List<BackupRecordeProductVo> getBackupRecordeProductVoForSysKeyword(String eduId, String keyword) {
        // 1、查询产品列表
        List<BrProductSysInfo> brProductSysInfoList = brProductSysInfoService.getList(null);
        // 1.1、查询各个服务器上安装的系统
        List<BrServerSysInfo> serverSysInfoList = brServerSysInfoService.list();
        // 1.2、查询备份记录列表
        List<BrBackupInfo> brBackupInfoList = brBackupInfoService.getRecentlyBackup(eduId);
        // 1.3、系统信息
        List<BrSysDatabaseInfo> brSysDatabaseInfoList = brSysDatabaseInfoService.getList(keyword);
        // 2、产品对应系统备份记录列表
        return getBackupRecordeProductVoList(brProductSysInfoList, serverSysInfoList, brBackupInfoList, brSysDatabaseInfoList);
    }

    /**
     * 获取指定系统备份记录列表
     *
     * @param pageSize 页大小
     * @param schoolId 学校ID
     * @param sysId    系统ID
     */
    public List<BrBackupInfoVo> getBackupRecordeSysInfo_pre(Integer pageSize, String schoolId, String sysId){
        List<BrBackupInfo> brBackupInfoList = brBackupInfoService.getListBySize(schoolId,sysId,pageSize);
        return BeanUtil.copyToList(brBackupInfoList, BrBackupInfoVo.class);
    }

    /**
     * 获取指定系统备份记录列表
     *
     * @param pageSize 页大小
     * @param eduId    教育局ID
     * @param sysId    系统ID
     */
    public List<BrBackupInfoVo> getBackupRecordeSysInfo(Integer pageSize, String eduId, String sysId) {
        List<BrBackupInfo> brBackupInfoList = brBackupInfoService.getListBySize(eduId, sysId, pageSize);
        if (CollectionUtil.isEmpty(brBackupInfoList)) {
            return new ArrayList<>();
        }
        List<BrBackupInfoVo> brBackupInfoVoList = BeanUtil.copyToList(brBackupInfoList, BrBackupInfoVo.class);
        brBackupInfoVoList.forEach(brBackupInfoVo -> {
            if (Objects.equals(brBackupInfoVo.getBackupFilePath(), BackupRestoreConstant.ERROR_BOOLEAN)) {
                brBackupInfoVo.setBeBackupError(BackupRestoreConstant.ERROR_EXIST);
                brBackupInfoVo.setBackupFilePath(BackupRestoreConstant.BACK_UP_ERROR);
            }
        });
        return brBackupInfoVoList;
    }

    /**
     * 获取还原全部备份时选择的备份列表
     *
     * @param eduId    教育局ID
     * @return 备份记录列表
     */
    public List<BrBackupInfoRestoreAllVo> getBackupRecordByRestoreAll(String eduId) {
        List<BrBackupInfoRestoreAllVo> backupInfoRestoreAllVoList = new ArrayList<>();
        // 1、获取全部备份类型列表
        List<BrBackupInfo> brBackupInfoList = brBackupInfoService.getList(eduId, BackupRestoreConstant.BACKUP_TYPE_ALL);
        if (CollectionUtil.isEmpty(brBackupInfoList)) {
            return backupInfoRestoreAllVoList;
        }
        // 2、转换为map
        Map<Long, String> map = brBackupInfoList.stream().collect(Collectors.toMap(BrBackupInfo::getBackupUniqueId, BrBackupInfo::getBackupUniqueDate, (k1, k2) -> k1));
        // 3、返回
        for (Map.Entry<Long, String> entry : map.entrySet()) {
            BrBackupInfoRestoreAllVo brBackupInfoRestoreAllVo = new BrBackupInfoRestoreAllVo();
            brBackupInfoRestoreAllVo.setBackupUniqueId(entry.getKey());
            brBackupInfoRestoreAllVo.setBackupUniqueDate(entry.getValue());
            backupInfoRestoreAllVoList.add(brBackupInfoRestoreAllVo);
        }
        return backupInfoRestoreAllVoList;
    }

}
